﻿using System;
using Domain;

namespace Presentation
{
    public class Presenter
    {
        private IView view;
        private InterpolationSearch interpolationSearch;
        public delegate void LogEventHandler(ILogger log);

        public Presenter(IView view)
        {
            this.view = view;
            interpolationSearch = new InterpolationSearch();
        }

        public void WriteToLog(ILogger logger)
        {
            string tab = "       ";
            string message = "INPUT:" + Environment.NewLine + Environment.NewLine;
            message += tab + "Array: " + view.array + Environment.NewLine;
            message += tab + "Element to find: " + view.elementToFind + Environment.NewLine;
            logger.Write(message);
            message = "OUTPUT:" + Environment.NewLine + Environment.NewLine;
            if (view.errorMessage == "")
            {
                message += tab + "Sorted array: " + view.sortedArray + Environment.NewLine;
                message += tab + "Position: " + view.position + Environment.NewLine;
            }
            else
            {
                message += tab + "Error message: " + view.errorMessage + Environment.NewLine;
            }
            logger.Write(message);
        }

        public void Search()
        {
            view.errorMessage = "";
            view.position = "";
            view.sortedArray = "";
            try
            {
                int[] array = GetArray();
                int elementToFind = GetElementToFind();

                Array.Sort(array);
                int position = interpolationSearch.FindElement(array, elementToFind);

                SetSortedArray(array);
                SetPosition(position);
            }
            catch (InputException e)
            {
                view.errorMessage = e.Message;
            }
        }

        private void SetPosition(int position)
        {
            view.position = position == -1 ? "Not found" : position.ToString();
        }

        private void SetSortedArray(int[] array)
        {
            string sortedArray = "";
            for(int i = 0; i < array.Length - 1; i++)
            {
                sortedArray += array[i].ToString() + ", ";
            }
            sortedArray += array[array.Length - 1].ToString();
            view.sortedArray = sortedArray;
        }

        public int GetElementToFind()
        {
            if (view.elementToFind.Equals(""))
            {
                throw new InputException(ErrorMessage.elementIsNotSet);
            }
            int elementToFind;
            try
            {
                elementToFind = Int32.Parse(view.elementToFind.Trim());
            }
            catch (FormatException)
            {
                throw new InputException(ErrorMessage.elementFormatIsIncorrect);
            }
            catch (OverflowException)
            {
                throw new InputException(ErrorMessage.elementIsLong);
            }
            return elementToFind;
        }

        public int[] GetArray()
        {
            if (view.array.Equals(""))
            {
                throw new InputException(ErrorMessage.arrayIsNotSet);
            }
            string [] split = view.array.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            int [] array = new int[split.Length];
            for ( int i = 0; i < split.Length; i++ )
            {
                try
                {
                    array[i] = Int32.Parse(split[i].Trim());
                }
                catch (FormatException)
                {
                    throw new InputException(ErrorMessage.arrayFormatIsIncorrect);
                }
                catch (OverflowException)
                {
                    throw new InputException(ErrorMessage.arrayContainsLongNumber);
                }
            }
            return array;
        }

        public void SetView(IView view)
        {
            this.view = view;
        }
    }
}
